package com.kakarote.authorization.service;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import com.kakarote.authorization.common.AuthorizationConst;
import com.kakarote.authorization.common.LoginType;
import com.kakarote.authorization.entity.AuthenticatedUser;
import com.kakarote.authorization.entity.AuthorizationUser;
import com.kakarote.core.entity.UserInfo;
import com.kakarote.core.feign.admin.entity.AdminUserInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 用户认证服务
 */

public interface UserAuthenticationService {

    Logger log = LoggerFactory.getLogger(UserAuthenticationService.class);


    /**
     * 用户查找
     *
     * @param authorizationUser 认证信息
     * @return 已认证用户
     */
    public AuthenticatedUser loadUser(AuthorizationUser authorizationUser);


    /**
     * 退出登录
     *
     * @param userInfo 当前登录用户
     */
    default void logout(UserInfo userInfo) {

    }


    /**
     * 是否支持该类型的认证
     *
     * @param loginType 认证类型
     * @return 是否支持
     */
    public boolean supports(LoginType loginType);


    /**
     * 是否是正常的用户
     *
     * @param userInfo  用户信息
     * @param extraData 额外数据
     * @return 用户是否正常，true为正常
     */
    public boolean isNormalUser(AdminUserInfo userInfo, Object extraData);

    /**
     * 验证参数是否正确
     *
     * @param authorizationUser 当前登录用户信息
     * @return true为正常
     */
    public boolean verifyParameter(AuthorizationUser authorizationUser);

    /**
     * 解密密码
     *
     * @param data 密文
     * @return 明文
     */
    default String decodePassWord(String data) {
        data = data.trim();
        RSA rsa = SecureUtil.rsa(AuthorizationConst.USER_PRIVATE_KEY, null);
        try {
            String str = rsa.decryptStr(data, KeyType.PrivateKey);
            long currentTimeMillis = System.currentTimeMillis();
            //当前时间戳的长度
            int length = Long.toString(currentTimeMillis).length();
            if (str.length() > length) {
                String time = StrUtil.sub(str, str.length() - length, str.length());
                if (NumberUtil.isNumber(time) && Math.abs(NumberUtil.parseLong(time) - currentTimeMillis) < 3000000) {
                    return StrUtil.sub(str, 0, str.length() - length);
                }
            }
        } catch (Exception ex) {
            log.error("解密数据失败", ex);
        }

        return data;
    }
}
